#include "StdAfx.h"
#include "cropimage.h"
#include <math.h>

const double EyeToLeft = 0.5;///0.5;
const double EyeToTop = 0.5;//0.50;
#define	LARGER(x,y) (((x)>(y))?(x):(y))
#define	SMALLER(x,y) (((x)<(y))?(x):(y))

wchar_t gImageFileName[MAX_PATH];

CCropImage::CCropImage(void)
{
}

CCropImage::~CCropImage(void)
{
}
BOOL CCropImage::AlignFaceRegion1(BYTE* pbyteSrcImg, int nWidth, int nHeight, 
								 KeyPoints keyPoint, BYTE * pbyteAlignedImg,
								 int nDstImgWidth, int nDstImgHeight)
{
	
//DWORD time1=GetTickCount();
	long	t3 = 0;
	int		 w, h,  x, y, t;

	int iOldX,iOldY ;//
	float  d, SinCita, CosCita, t1, t2;
	POINT	LeftIrisPos, RightIrisPos, MouthPos;

	LeftIrisPos  = keyPoint.LeftEye;
	RightIrisPos = keyPoint.RightEye;
	MouthPos = keyPoint.Mouth;
	
	w = Convert2Stride(nWidth);
	h = nHeight;
	d = PointDistance(LeftIrisPos, RightIrisPos);

	SinCita = (-RightIrisPos.y + LeftIrisPos.y) / d;
	CosCita = (RightIrisPos.x  - LeftIrisPos.x) / d;

	POINT IrisMidPos;
	IrisMidPos.x = (LeftIrisPos.x + RightIrisPos.x) / 2;
	IrisMidPos.y = (LeftIrisPos.y + RightIrisPos.y) / 2;

	/////////////Place the original at the center of the face//////
	x = LeftIrisPos.x - IrisMidPos.x;
	y = LeftIrisPos.y - IrisMidPos.y;
	t = x;	x = -y;	y = -t;
	x += IrisMidPos.x;
	y += IrisMidPos.y;
    POINT fixpos;
	fixpos.x = x;
	fixpos.y = y;
	

	BYTE* pOriData = pbyteSrcImg;

	//cal the new pos of the iris in the new face
	LeftIrisPos.x = fixpos.x + (int)(CosCita * (LeftIrisPos.x - fixpos.x)
						 - SinCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	LeftIrisPos.y = fixpos.y + (int)(SinCita * (LeftIrisPos.x - fixpos.x)
						 + CosCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	
	RightIrisPos.x = fixpos.x + (int)(CosCita * (RightIrisPos.x - fixpos.x)
						- SinCita * (RightIrisPos.y - fixpos.y) + 0.5);
	RightIrisPos.y = fixpos.y + (int)(SinCita * (RightIrisPos.x - fixpos.x)
						+ CosCita * (RightIrisPos.y - fixpos.y) + 0.5);
	
	
	////////////////crop according to the mean face structure///////////////
	float wh_Rate = (float)nDstImgWidth / (float)nDstImgHeight;

	int	nLeft = int(LeftIrisPos.x - EyeToLeft * d + 0.5);//0.8-old ratio//0.6
	int nRight = RightIrisPos.x + (LeftIrisPos.x - nLeft);
	//int	nRight = int(RightIrisPos.x + EyeToLeft * d + 0.5);
	
	int	nTop  = int(LeftIrisPos.y - EyeToTop * d + 0.5);//1-old ratio//0.6
	int	nBottom = (int) (nRight - nLeft + 1) / wh_Rate + nTop - 1;

	if(0)
	{
		bool IsIllCut;
		IsIllCut = false;
		if(nRight > nWidth-1 || nBottom > nHeight-1|| nLeft < 0 || nTop < 0)
		{
			return FALSE;
		}
	}


	RECT	rectFaceRgn;
	rectFaceRgn.left = nLeft;
	rectFaceRgn.top = nTop;
	rectFaceRgn.right = nRight;
	rectFaceRgn.bottom = nBottom;

	int	nCropWidth = nRight - nLeft + 1;
	int nCropHeight= nBottom - nTop + 1;

	int nCropStride= Convert2Stride(nCropWidth);

	rectFaceRgn.right=rectFaceRgn.left+nCropStride;
	rectFaceRgn.bottom = rectFaceRgn.top+nCropHeight;

	float xScale, yScale, fX, fY;
	xScale = (float)nCropStride  / (float)nDstImgWidth;
	yScale = (float)nCropHeight / (float)nDstImgHeight;	
	for(y=0;y<nDstImgHeight;++y)
	{
		fY = y * yScale;

		t1 = SinCita * (rectFaceRgn.top+fY - fixpos.y);
		t2 = CosCita * (rectFaceRgn.top+fY - fixpos.y);
		
		for(x=0;x<nDstImgWidth;++x)
		{
			fX = x * xScale;
			
			if(  rectFaceRgn.left+ (int)fX >=0 && 
				(int)(rectFaceRgn.top+fY) >=0 && 
				rectFaceRgn.left+ (int)fX  <w && 
				(int)(rectFaceRgn.top+fY)  <h )
			{
				
				iOldX = int(fixpos.x +  (CosCita * (rectFaceRgn.left+ (int)fX - fixpos.x) + t1));
				iOldY = int(fixpos.y +  (t2 - SinCita * (rectFaceRgn.left+ (int)fX - fixpos.x)));
					
				pbyteAlignedImg[y*nDstImgWidth+x] = pOriData[iOldY * w + iOldX];//pTempData[ (int) (rectFaceRgn.top+fY)*w + rectFaceRgn.left+ (int)fX];
			}
			else
				pbyteAlignedImg[y*nDstImgWidth+x] = 0;
			
		}
	}

	return TRUE;
}
BOOL CCropImage::AlignFaceRegion(BYTE* pbyteSrcImg, int nWidth, int nHeight, 
								 KeyPoints keyPoint, BYTE * pbyteAlignedImg,
								 int nDstImgWidth, int nDstImgHeight)
{
	
	long	t3 = 0;
	int		i, j, w, h, x1, x, y, t;
///	double	oldx, oldy, cofX, cofY, FTmp; // for old rotation method 
	int iOldX,iOldY , iTemp;//add for new rotation coding
	double  d, SinCita, CosCita, t1, t2;
	POINT	LeftIrisPos, RightIrisPos, MouthPos;

	LeftIrisPos  = keyPoint.LeftEye;
	RightIrisPos = keyPoint.RightEye;
	MouthPos = keyPoint.Mouth;
	
	w = Convert2Stride(nWidth);
	h = nHeight;
	d = PointDistance(LeftIrisPos, RightIrisPos);

	SinCita = (-RightIrisPos.y + LeftIrisPos.y) / d;
	CosCita = (RightIrisPos.x  - LeftIrisPos.x) / d;

	POINT IrisMidPos;
	IrisMidPos.x = (LeftIrisPos.x + RightIrisPos.x) / 2;
	IrisMidPos.y = (LeftIrisPos.y + RightIrisPos.y) / 2;

	/////////////Place the original at the center of the face//////
	x = LeftIrisPos.x - IrisMidPos.x;
	y = LeftIrisPos.y - IrisMidPos.y;
	t = x;	x = -y;	y = -t;
	x += IrisMidPos.x;
	y += IrisMidPos.y;
    POINT fixpos;
	fixpos.x = x;
	fixpos.y = y;
	
	
//DWORD time1=GetTickCount();
	///////////////////rotate the image////////////////////////////
	BYTE* pRotatedImg = new BYTE[w*h];
	BYTE* pOriData = pbyteSrcImg;
	BYTE* pTempData = pRotatedImg;
/* old rotate code using bilinear interpolation
//////////////////////////////////////////////////////////////////////
	for(j=0; j<h; j++)
	{
		t1 = SinCita * (j - fixpos.y);
		t2 = CosCita * (j - fixpos.y);
		//t1 = n * (j - IrisMidPos.y);
		//t2 = q * (j - IrisMidPos.y);
		for(i=0; i<w; i++)
		{
			oldx = fixpos.x +  (CosCita * (i - fixpos.x) + t1);
			oldy = fixpos.y +  (t2 - SinCita * (i - fixpos.x));
			//oldx = IrisMidPos.x +  (m * (i - IrisMidPos.x) + t1);
			//oldy = IrisMidPos.y +  (t2 + p * (i - IrisMidPos.x));
			if(oldx < w-1 && oldy < h-1 && oldx >= 0 && oldy >= 0)
			{	
				cofX = oldx - int(oldx);
				cofY = oldy - int(oldy);
				x1 = ((int)oldy) * w + (int)oldx;
				FTmp = (1-cofX) * (double)pOriData[x1] + cofX * (double)pOriData[x1 + 1];
				FTmp = (1-cofY) * FTmp + cofY * ((1-cofX) * (double)pOriData[x1 + w] + cofX * (double)pOriData[x1 + w + 1]);
				pTempData[j * w + i] = BYTE(((FTmp + 0.5)>255)?255:(FTmp + 0.5));
			}
			else 
				pTempData[j * w + i] = 0;
		}
	}*/
////////////////////////////////////////////////////////////////////
	for(j=0; j<h; j++)
	{
		t1 = SinCita * (j - fixpos.y);
		t2 = CosCita * (j - fixpos.y);
		//t1 = n * (j - IrisMidPos.y);
		//t2 = q * (j - IrisMidPos.y);
		for(i=0; i<w; i++)
		{
			iOldX = int(fixpos.x +  (CosCita * (i - fixpos.x) + t1));
			iOldY = int(fixpos.y +  (t2 - SinCita * (i - fixpos.x)));
			//oldx = IrisMidPos.x +  (m * (i - IrisMidPos.x) + t1);
			//oldy = IrisMidPos.y +  (t2 + p * (i - IrisMidPos.x));
			if(iOldX < w-1 && iOldY < h-1 && iOldX >= 0 && iOldY >= 0)
			{	
				iTemp = pOriData[iOldY * w + iOldX];
				pTempData[j * w + i] = (iTemp>255) ? 255: iTemp;
			}
			else 
				pTempData[j * w + i] = 0;
		}
	}
/////////////////////////////////////////////////////////////////////////////////
//DWORD time2=GetTickCount();
//_DebugInfo("c:/crop.txt","time1=%d",time2-time1);	
	//cal the new pos of the iris in the new face
	LeftIrisPos.x = fixpos.x + (int)(CosCita * (LeftIrisPos.x - fixpos.x)
						 - SinCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	LeftIrisPos.y = fixpos.y + (int)(SinCita * (LeftIrisPos.x - fixpos.x)
						 + CosCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	
	RightIrisPos.x = fixpos.x + (int)(CosCita * (RightIrisPos.x - fixpos.x)
						- SinCita * (RightIrisPos.y - fixpos.y) + 0.5);
	RightIrisPos.y = fixpos.y + (int)(SinCita * (RightIrisPos.x - fixpos.x)
						+ CosCita * (RightIrisPos.y - fixpos.y) + 0.5);
	
	
	////////////////crop according to the mean face structure///////////////
	double wh_Rate = (double)nDstImgWidth / (double)nDstImgHeight;

	int	nLeft = int(LeftIrisPos.x - EyeToLeft * d + 0.5);//0.8-old ratio//0.6
	int nRight = RightIrisPos.x + (LeftIrisPos.x - nLeft);
	//int	nRight = int(RightIrisPos.x + EyeToLeft * d + 0.5);
	
	int	nTop  = int(LeftIrisPos.y - EyeToTop * d + 0.5);//1-old ratio//0.6
	int	nBottom = (nRight - nLeft + 1) / wh_Rate + nTop - 1;

	if(0)
	{
		bool IsIllCut;
		IsIllCut = false;
		if(nRight > nWidth-1 || nBottom > nHeight-1|| nLeft < 0 || nTop < 0)
		{
			delete pRotatedImg;
			return FALSE;
		}
			


		if(IsIllCut)
		{
			nLeft = LARGER(nLeft, 0);
			nTop  = LARGER(nTop, 0);

			nRight = SMALLER(nRight, nWidth-1);
			nBottom= SMALLER(nBottom, nHeight-1);  


			int nSize = SMALLER(nRight - nLeft + 1,int(( nBottom - nTop + 1) * wh_Rate));
			nBottom= nTop + int(nSize/wh_Rate) - 1;//1.25
		}
	}


	RECT	rectFaceRgn;
	rectFaceRgn.left = nLeft;
	rectFaceRgn.top = nTop;
	rectFaceRgn.right = nRight;
	rectFaceRgn.bottom = nBottom;

	int	nCropWidth = nRight - nLeft + 1;
	int nCropHeight= nBottom - nTop + 1;

	int nCropStride= Convert2Stride(nCropWidth);

	rectFaceRgn.right=rectFaceRgn.left+nCropStride;
	rectFaceRgn.bottom = rectFaceRgn.top+nCropHeight;
	

 	BYTE*	pCropImgData = new BYTE[nCropStride * nCropHeight];
	memset(pCropImgData,0,nCropStride * nCropHeight);
//time1=GetTickCount();
	if(0)
		CropSubImage(pRotatedImg, nWidth, nHeight, pCropImgData, rectFaceRgn);
	else
		CropImage(pRotatedImg, nWidth, nHeight, pCropImgData, rectFaceRgn);
//time2=GetTickCount();
//_DebugInfo("c:/crop.txt","time2=%d",time2-time1);
	delete []pRotatedImg;
//time1=GetTickCount();
	ResizeImage(pCropImgData, nCropWidth, nCropHeight, pbyteAlignedImg, nDstImgWidth, nDstImgHeight);
//time2=GetTickCount();
//_DebugInfo("c:/crop.txt","time3=%d",time2-time1);
	//////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////
	delete []pCropImgData;
	return TRUE;
/*///old code
    long	t3 = 0;
	int		i, j, w, h, x1, x, y, t;
	double	oldx, oldy, cofX, cofY, FTmp;
	double  d, SinCita, CosCita, t1, t2;
	POINT	LeftIrisPos, RightIrisPos, MouthPos;

	LeftIrisPos  = keyPoint.LeftEye;
	RightIrisPos = keyPoint.RightEye;
	MouthPos = keyPoint.Mouth;
	
	w = Convert2Stride(nWidth);
	h = nHeight;
	d = PointDistance(LeftIrisPos, RightIrisPos);

	SinCita = (-RightIrisPos.y + LeftIrisPos.y) / d;
	CosCita = (RightIrisPos.x  - LeftIrisPos.x) / d;

	POINT IrisMidPos;
	IrisMidPos.x = (LeftIrisPos.x + RightIrisPos.x) / 2;
	IrisMidPos.y = (LeftIrisPos.y + RightIrisPos.y) / 2;

	/////////////Place the original at the center of the face//////
	x = LeftIrisPos.x - IrisMidPos.x;
	y = LeftIrisPos.y - IrisMidPos.y;
	t = x;	x = -y;	y = -t;
	x += IrisMidPos.x;
	y += IrisMidPos.y;
    POINT fixpos;
	fixpos.x = x;
	fixpos.y = y;
	
	

	///////////////////rotate the image////////////////////////////
	BYTE* pRotatedImg = new BYTE[w*h];
	BYTE* pOriData = pbyteSrcImg;
	BYTE* pTempData = pRotatedImg;
	for(j=0; j<h; j++)
	{
		t1 = SinCita * (j - fixpos.y);
		t2 = CosCita * (j - fixpos.y);
		//t1 = n * (j - IrisMidPos.y);
		//t2 = q * (j - IrisMidPos.y);
		for(i=0; i<w; i++)
		{
			oldx = fixpos.x +  (CosCita * (i - fixpos.x) + t1);
			oldy = fixpos.y +  (t2 - SinCita * (i - fixpos.x));
			//oldx = IrisMidPos.x +  (m * (i - IrisMidPos.x) + t1);
			//oldy = IrisMidPos.y +  (t2 + p * (i - IrisMidPos.x));
			if(oldx < w-1 && oldy < h-1 && oldx >= 0 && oldy >= 0)
			{	
				cofX = oldx - int(oldx);
				cofY = oldy - int(oldy);
				x1 = ((int)oldy) * w + (int)oldx;
				FTmp = (1-cofX) * (double)pOriData[x1] + cofX * (double)pOriData[x1 + 1];
				FTmp = (1-cofY) * FTmp + cofY * ((1-cofX) * (double)pOriData[x1 + w] + cofX * (double)pOriData[x1 + w + 1]);
				pTempData[j * w + i] = BYTE(((FTmp + 0.5)>255)?255:(FTmp + 0.5));
			}
			else 
				pTempData[j * w + i] = 0;
		}
	}
	
	//cal the new pos of the iris in the new face
	LeftIrisPos.x = fixpos.x + (int)(CosCita * (LeftIrisPos.x - fixpos.x)
						 - SinCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	LeftIrisPos.y = fixpos.y + (int)(SinCita * (LeftIrisPos.x - fixpos.x)
						 + CosCita * (LeftIrisPos.y - fixpos.y) + 0.5);
	
	RightIrisPos.x = fixpos.x + (int)(CosCita * (RightIrisPos.x - fixpos.x)
						- SinCita * (RightIrisPos.y - fixpos.y) + 0.5);
	RightIrisPos.y = fixpos.y + (int)(SinCita * (RightIrisPos.x - fixpos.x)
						+ CosCita * (RightIrisPos.y - fixpos.y) + 0.5);
	
	
	////////////////crop according to the mean face structure///////////////
	double wh_Rate = (double)nDstImgWidth / (double)nDstImgHeight;

	int	nLeft = int(LeftIrisPos.x - EyeToLeft * d + 0.5);//0.8-old ratio//0.6
	int nRight = RightIrisPos.x + (LeftIrisPos.x - nLeft);
	//int	nRight = int(RightIrisPos.x + EyeToLeft * d + 0.5);
	
	int	nTop  = int(LeftIrisPos.y - EyeToTop * d + 0.5);//1-old ratio//0.6
	int	nBottom = (nRight - nLeft + 1) / wh_Rate + nTop - 1;

	bool IsIllCut;
	IsIllCut = false;
	if(nRight > nWidth-1 || nBottom > nHeight-1|| nLeft < 0 || nTop < 0)
	{
		FILE * f_err = fopen("D:\\IllImageName.txt", "wt");
		fprintf(f_err, "%s\n", gImageFileName);
		fclose(f_err);
		IsIllCut = true;
		
	}


	if(IsIllCut)
	{
		nLeft = LARGER(nLeft, 0);
		nTop  = LARGER(nTop, 0);

		nRight = SMALLER(nRight, nWidth-1);
		nBottom= SMALLER(nBottom, nHeight-1);  


		int nSize = SMALLER(nRight - nLeft + 1,int(( nBottom - nTop + 1) * wh_Rate));
		nBottom= nTop + int(nSize/wh_Rate) - 1;//1.25
	}
	RECT	rectFaceRgn;
	rectFaceRgn.left = nLeft;
	rectFaceRgn.top = nTop;
	rectFaceRgn.right = nRight;
	rectFaceRgn.bottom = nBottom;

	int	nCropWidth = nRight - nLeft + 1;
	int nCropHeight= nBottom - nTop + 1;

	int nCropStride= Convert2Stride(nCropWidth);
	
 	BYTE*	pCropImgData = new BYTE[nCropStride * nCropHeight];

	CropSubImage(pRotatedImg, nWidth, nHeight, pCropImgData, rectFaceRgn);
	delete []pRotatedImg;

	ResizeImage(pCropImgData, nCropWidth, nCropHeight, pbyteAlignedImg, nDstImgWidth, nDstImgHeight);
	/////////////////////////////////////////////////////////////////////


	delete []pCropImgData;
	return TRUE;*/
	
}

int CCropImage::Convert2Stride(int nWidth)
{
	return ((nWidth%4)?(nWidth+4-nWidth%4):(nWidth));
}

double CCropImage::PointDistance(POINT p1, POINT p2)
{
	return sqrt(static_cast<double>((p2.y-p1.y) * (p2.y-p1.y) + (p2.x-p1.x) * (p2.x-p1.x)));
}
void CCropImage::CropImage( BYTE* all, int iWidth, int iHeight, BYTE* part, RECT rcRect )
{
	int left=rcRect.left;
	int right=rcRect.right;
	int top=rcRect.top;
	int bottom=rcRect.bottom;

	int w = right - left;
	int h = bottom - top;

	for( int i=0; i<h; i++ )
	{
		for( int j=0; j<w; j++ )
		{
			if(left+j >= 0 && top +i >=0 && left+j<iWidth && top +i <iHeight)
				part[j+i*w] = all[(left+j)+(top+i)*iWidth];
		}
	}
}
BOOL CCropImage::CropSubImage(BYTE * pbyteSrcImgData, int nSrcImgWidth, int nSrcImgHeight, BYTE * pDstImgData, RECT subRect)
{
	int		left	= subRect.left;
	int		top		= subRect.top;
	int		right	= subRect.right;
	int		bottom	= subRect.bottom;

	int width  = right - left + 1;
	int height = bottom - top + 1;
	int stride = Convert2Stride(width);
	
	int	nSrcStride = Convert2Stride(nSrcImgWidth);
	
//	assert( width > 0 && height > 0 && left >= 0 && right >=0 && top >= 0 && bottom >= 0 && right < nSrcImgWidth && bottom < nSrcImgHeight);
	
	int i;
	BYTE *pS = pbyteSrcImgData + top * nSrcStride + left;
	BYTE *pD = pDstImgData;
	for(i=0; i<height; i++)
	{
		CopyMemory( (void*)pD, (void*)pS, width);
		pS += nSrcStride;
		pD += stride;
	}
	return true;
}

BOOL CCropImage::ResizeImage(const BYTE * pSrcImg, int nSrcWidth, int nSrcHeight,
							 BYTE * pDstImg, int nDstWidth, int nDstHeight)
{
	/*
	int		n_x_d, n_y_d;
	int		n_x_s, n_y_s;
	double	lfXscl, lfYScl, lf_x_s, lf_y_s, lfNewGray;
	double	lfWeight_x, lfWeight_y;

	if(nSrcWidth == nDstWidth && nSrcHeight == nDstHeight)
	{
		memcpy(pDstImg, pSrcImg, Convert2Stride(nSrcWidth)*nSrcHeight);
		return TRUE;
	}

	lfXscl = double(nSrcWidth) / nDstWidth;
	lfYScl = double(nSrcHeight) / nDstHeight;

	nSrcWidth = Convert2Stride(nSrcWidth);
	nDstWidth = Convert2Stride(nDstWidth);

	for(n_y_d=0; n_y_d<nDstHeight; n_y_d++)
	{
		for(n_x_d=0; n_x_d<nDstWidth; n_x_d++)
		{
			lf_x_s = lfXscl * (n_x_d + 1) - 1;
			lf_y_s = lfYScl * (n_y_d + 1) - 1;
			n_x_s = int(lf_x_s);
			n_x_s = SMALLER(n_x_s, nSrcWidth - 2);
			n_y_s = int(lf_y_s);
			n_y_s = SMALLER(n_y_s, nSrcHeight - 2);
			lfWeight_x = lf_x_s - n_x_s;
			lfWeight_y = lf_y_s - n_y_s;
			lfNewGray = (1 - lfWeight_y) * ((1 - lfWeight_x) * pSrcImg[n_y_s * nSrcWidth + n_x_s]
			           + lfWeight_x * pSrcImg[n_y_s * nSrcWidth + n_x_s + 1])
					   + lfWeight_y * ((1 - lfWeight_x) * pSrcImg[(n_y_s + 1) * nSrcWidth + n_x_s]
					   + lfWeight_x * pSrcImg[(n_y_s + 1) * nSrcWidth + n_x_s+1]);
			
			pDstImg[n_y_d * nDstWidth + n_x_d] = BYTE(lfNewGray);
		}
	}
	return TRUE;
	*/


	int		n_x_d, n_y_d;
	int		n_x_s, n_y_s;
	double	lfXscl, lfYScl, lf_x_s, lf_y_s, lfNewGray;
	double	lfWeight_x, lfWeight_y;

	if(nSrcWidth == nDstWidth && nSrcHeight == nDstHeight)
	{
		memcpy(pDstImg, pSrcImg, Convert2Stride(nSrcWidth)*nSrcHeight);
		return TRUE;
	}

	lfXscl = double(nSrcWidth) / nDstWidth;
	lfYScl = double(nSrcHeight) / nDstHeight;

	nSrcWidth = Convert2Stride(nSrcWidth);
	nDstWidth = Convert2Stride(nDstWidth);

	for(n_y_d=0; n_y_d<nDstHeight; n_y_d++)
	{
		for(n_x_d=0; n_x_d<nDstWidth; n_x_d++)
		{
			lf_x_s = lfXscl * (n_x_d + 1) - 1;
			lf_y_s = lfYScl * (n_y_d + 1) - 1;
			n_x_s = int(lf_x_s);
			n_x_s = SMALLER(n_x_s, nSrcWidth - 2);
			n_y_s = int(lf_y_s);
			n_y_s = SMALLER(n_y_s, nSrcHeight - 2);
			lfWeight_x = lf_x_s - n_x_s;
			lfWeight_y = lf_y_s - n_y_s;
			lfNewGray = (1 - lfWeight_y) * ((1 - lfWeight_x) * pSrcImg[n_y_s * nSrcWidth + n_x_s]
			           + lfWeight_x * pSrcImg[n_y_s * nSrcWidth + n_x_s + 1])
					   + lfWeight_y * ((1 - lfWeight_x) * pSrcImg[(n_y_s + 1) * nSrcWidth + n_x_s]
					   + lfWeight_x * pSrcImg[(n_y_s + 1) * nSrcWidth + n_x_s+1]);
			
			pDstImg[n_y_d * nDstWidth + n_x_d] = BYTE(lfNewGray);
		}
	}
	return TRUE;

}
BOOL CCropImage::ResizeImage_Eye(const BYTE * pSrcImg, int nSrcWidth, int nSrcHeight,
							 BYTE * pDstImg, int nDstWidth, int nDstHeight)
{
	int		n_x_d, n_y_d;
	int		n_x_s, n_y_s;
	double	lfXscl, lfYScl, lf_x_s, lf_y_s, lfNewGray;
	double	lfWeight_x, lfWeight_y;

	if(nSrcWidth == nDstWidth && nSrcHeight == nDstHeight)
	{
		memcpy(pDstImg, pSrcImg, nSrcWidth * nSrcHeight);
		return TRUE;
	}

	lfXscl = double(nSrcWidth+0.0)/nDstWidth;
	lfYScl = double(nSrcHeight+0.0)/nDstHeight;

	//if the image data is strided, open the following 2 lines
	for(n_y_d=0; n_y_d<nDstHeight; n_y_d++)
	{
		for(n_x_d=0; n_x_d<nDstWidth; n_x_d++)
		{
			lf_x_s = lfXscl * n_x_d;
			lf_y_s = lfYScl * n_y_d;
			n_x_s = int(lf_x_s);
			n_x_s = SMALLER(n_x_s, nSrcWidth-2);
			n_y_s = int(lf_y_s);
			n_y_s = SMALLER(n_y_s, nSrcHeight-2);
			lfWeight_x = lf_x_s - n_x_s;
			lfWeight_y = lf_y_s - n_y_s;
			lfNewGray = (1-lfWeight_y)*((1-lfWeight_x)*pSrcImg[n_y_s*nSrcWidth+n_x_s]+lfWeight_x*pSrcImg[n_y_s*nSrcWidth+n_x_s+1])+
						lfWeight_y*((1-lfWeight_x)*pSrcImg[(n_y_s+1)*nSrcWidth+n_x_s]+lfWeight_x*pSrcImg[(n_y_s+1)*nSrcWidth+n_x_s+1]);
			pDstImg[n_y_d*nDstWidth+n_x_d] = BYTE(lfNewGray);
		}
	}
	return TRUE;
}

void CCropImage::SaveBmpFile(CString szFileName, BYTE * srcImage, int Width, int Height)
{
	BITMAPFILEHEADER bmfHdr;

	int nImgHeight=(Width+3)/4*4;
	int imageSize=nImgHeight*Height;
	
	BYTE *saveImage=new BYTE[imageSize];
	memset(saveImage,0,imageSize);
	for(int i=0;i<Height;i++)
		memcpy(saveImage+i*nImgHeight,srcImage+i*Width,Width);

	bmfHdr.bfType=0x4d42; 
    bmfHdr.bfSize=imageSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD); 
    bmfHdr.bfReserved1=0; 
    bmfHdr.bfReserved2=0; 
    bmfHdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD); 

	BITMAPINFO *pInfo=(BITMAPINFO*)malloc(sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD));
	pInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 
    pInfo->bmiHeader.biWidth=Width; 
    pInfo->bmiHeader.biHeight=Height; 
    pInfo->bmiHeader.biPlanes=1; 
    pInfo->bmiHeader.biBitCount=8; 
    pInfo->bmiHeader.biCompression=BI_RGB; 
    pInfo->bmiHeader.biSizeImage=imageSize; 
    pInfo->bmiHeader.biXPelsPerMeter=0; 
    pInfo->bmiHeader.biYPelsPerMeter=0; 
    pInfo->bmiHeader.biClrUsed=0; 
    pInfo->bmiHeader.biClrImportant=0; 

  	for(int i=0;i<256;i++)
	{
		pInfo->bmiColors[i].rgbBlue=i;
		pInfo->bmiColors[i].rgbGreen=i;
		pInfo->bmiColors[i].rgbRed=i;
		pInfo->bmiColors[i].rgbReserved=0;
	}

	FILE* mFile =fopen(szFileName,"wb");
	fwrite((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER),1,mFile);
    fwrite(pInfo,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD),1, mFile);
	fwrite(saveImage,sizeof(BYTE),imageSize,mFile); 
	fclose(mFile);
	
	free(pInfo);
	delete[]saveImage;
}
